package com.skywork.controller.advice;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.skywork.controller.response.base.BaseResponse;
import com.skywork.domain.Channel;
import com.skywork.utils.ChannelKit;
import com.skywork.utils.RSAUtils;

@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> {

	private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

	@Autowired
	private AbstractJackson2HttpMessageConverter abstractJackson2HttpMessageConverter;

	@Override
	@SuppressWarnings("rawtypes")
	public boolean supports(MethodParameter returnType, Class converterType) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	@SuppressWarnings("rawtypes")
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
		Channel channel = ChannelKit.getChannel();
		LOGGER.info("Channel:{}", channel);
		if (channel != null) {
			ObjectMapper objectMapper = abstractJackson2HttpMessageConverter.getObjectMapper();

			try {
				// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
				// objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

				LOGGER.info("Response URI:{}, Body:{}", request.getURI(), objectMapper.writeValueAsString(body));

				String encryptKey = channel.getEncryptKey();
				if (StringUtils.isNotBlank(encryptKey)) {
					// responseStr = DigestUtils.md5Hex(responseStr);

					BaseResponse baseResponse = objectMapper.convertValue(body, BaseResponse.class);
					if (baseResponse.getData() != null) {
						String data = objectMapper.writeValueAsString(baseResponse.getData());
						String encryptStr = RSAUtils.encryptByPublicKey(data, encryptKey);// .encryptByPublicKey(data.getBytes());
						LOGGER.info("String:{}, encryptStr:{}", data, encryptStr);
						baseResponse.setEncryptStr(encryptStr);
						// = Base64.encodeBase64String(encrypt);
						// responseStr =
						// Base64.encodeBase64String(encryptedData);
						LOGGER.info("Response Encrypt Body:{}", encryptStr);
						// RSAUtils rSAUtils = new RSAUtils();

						// rSAUtils.setPrivateKey(privateKey);

						// byte[] decryptedData =
						// RSAUtils.decryptByPrivateKey(encryptedData,"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJ93OORCPrEQeFgstjVeubgpc+ETK6zUUw1rsUvSvcIqBg8tbY164og8BP/7Rpjkm0HMZrDUQhYc/8zakDLbkjwcftFDHsrZDKHOznFPz739Gu2LptATwddKSWQJ5Q6qS6/mcuXOhqbSGDXbnw/uFslMyFn1RPMchNNzjuq4hfN9AgMBAAECgYBCxvY3/9Wo6DC9G9whdU1oZVN1SUXc1f0Bfbt8+P8ls9tdt7RMrsz2J8wgNeVWWUT6xNGr8vbJs9MawdvosDIH+ICoXcP4y9PGzScnjTaXeLGL7Atnhxg3jZseNZfkXHPZj9pQVCY5jaayUUbBLguD1KKXR1Ab6qG2TSBmbemGMQJBANfLz4/X60q/cSlQZG5Y5ZJUSeYfw94EEZeeW0/1ywDEXyj036N6JSP4/YUPaUhjkUpptghYmYewfRZunRBssLMCQQC9LMk5X8+zMrYHh+53vQYE+nXZePwkbkWzF0dnh4SLkJZeKQ/rx9YB2TjvdQY76cB/FQ+qcDgMn8r5xoizVIMPAkBQkRNJTP/XxGnnVtBoMmBjpXyBolJqTXKT/Ndynv3Pp4EvtVzZl/zN1WQxjXNtR18zPQxtSUbo1gednGaffzTpAkBUhI3idEv3Y9CvzKteE7V8w+mjH8qG/D1nph7gwksVj6OerfnO/Zk/ei1VzpLacbTvEhnNrBVejoXA0lKAzGFBAkBy6pYc2ka7ThflFqJfiHs4AklVY8jNUZxVQzmbIax6vQx4SDtenmDboCucrHDk6XPlS2hDlHjDis6brJ6M7iBD");
						// LOGGER.info("解密后:\r\n"+new String(decryptedData));
						body = baseResponse;
					}
				}

			} catch (Exception e) {
				LOGGER.error(e.getMessage(), e);

			} finally {
				ChannelKit.removeThreadLocal();
			}
		}
		return body;

	}

}
